
// ===============================================================================================================
// -*- C++ -*-
//
// ProgressiveMesh.hpp - Progressive Mesh implementation, based on the algorithms presented here:
// http://www.melax.com/polychop - By Stan Melax.
//
// Copyright (c) 2010 Guilherme R. Lampert
// guilherme.ronaldo.lampert@gmail.com
//
// This code is licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// above is included in the resulting source code.
//
// ===============================================================================================================

#ifndef __PROGRESSIVE_MESH_HPP__
#define __PROGRESSIVE_MESH_HPP__

// == External Modules ======

#include "Utility.hpp"
#include "Mesh.hpp"
#include "Array.hpp"
#include "MeshOptimize.hpp"

// ==============================================
// Progressive Mesh Class (For Polygon Reduction)
// ==============================================

class ProgressiveMesh {

public:

	ProgressiveMesh(const Mesh * pMesh, int maxVerts, float LOD = 0.5f, float morph = 1.0f);

	// Write the current optimized mesh to an .obj file.
	bool SavePMeshToWavefrontObject(const std::string & filename) const;

	// Render based on Level-Of-Detail.
	void Render() const;

	// Check if initialization was successful.
	bool Good() const;

	void SetScale(float s);

	void SetRenderMode(const Mesh::RenderMode m);

	void SetLOD(float newLOD);

	void SetMaxVertices(int newMax);

	void SetMorph(float newMorph);

	~ProgressiveMesh();

private:

	ProgressiveMesh() { }

	int MapLookup(int x, int y) const;

	void PermuteVertices(const Array<int> & Permutation);

private:

	int m_MaxVerts;  // Maximum number of vertices to draw.
	float m_LodBase; // Fraction of vertices used to morph toward.
	float m_Morph;   // Where to render between 2 levels of detail.

	Array<int> m_CollapseMap;

	// Mesh Attributes:

	float m_ScaleFactor;
	Mesh::RenderMode m_RenderMode;

	Array<Triangle> m_Triangles;
	Array<Vec3> m_Vertices;
};

#endif // __PROGRESSIVE_MESH_HPP__
